Visualizaciones Univariables¶

Gráficos de Barras¶

Los gráficos de barras, también llamados gráficos de columnas o barplot, nos sirven para mostrar magnitudes de variables numéricas a lo largo de diferentes grupos o categorías en el eje horizontal X, y en el eje vertical Y tendremos los valores numéricos, Luego se alza una barra de cada punto del eje X hasta el valor numérico eje Y que le corresponde a esa categoría en esa variable.

Este tipo de gráfico se usa principalmente para comparar variables numéricas de diferentes grupos en los datos y cuando se quiere enfatizar cambios de magnitudes que hay entre estas variables a lo largo de diferentes grupos, los gráficos de barras múltiples y gráficos de barra apiladas son las variantes de este.

No se debería utilizar estos gráficos en los siguientes casos:

  • Cuando se quiera comparar valores de muchas categorías.
  • Si se quieren comparar proporciones porcentuales de dos o más variables.
  • Para obtener información de la distribución de las variables

A continuación utilizaremos el data set de Titanic para visualizar algunos ejemplos del gráfico de barra, este se realizará con tres diferentes librerías pandas, seaborn y matplotlib.

In [2]:
import pandas as pd # cargamos librerias
import seaborn as sns
import matplotlib.pyplot as plt
import plotly.express as px
In [3]:
# cambio de dimensiones de canvas de manera global

plt.rcParams['figure.figsize'] = (8,5)
In [4]:
df = pd.read_csv('./datasets/titanic.csv') # en este caso utilizaremos el data set titanic
df
Out[4]:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
... ... ... ... ... ... ... ... ... ... ... ... ...
886 887 0 2 Montvila, Rev. Juozas male 27.0 0 0 211536 13.0000 NaN S
887 888 1 1 Graham, Miss. Margaret Edith female 19.0 0 0 112053 30.0000 B42 S
888 889 0 3 Johnston, Miss. Catherine Helen "Carrie" female NaN 1 2 W./C. 6607 23.4500 NaN S
889 890 1 1 Behr, Mr. Karl Howell male 26.0 0 0 111369 30.0000 C148 C
890 891 0 3 Dooley, Mr. Patrick male 32.0 0 0 370376 7.7500 NaN Q

891 rows × 12 columns

¿Cuantos pasajeros hombres y cuantas pasajeras mujeres habian en el Titanic.?

In [5]:
pasajeros_sexo = df.groupby('Sex').agg({
    'PassengerId':'count'
})

pasajeros_sexo
Out[5]:
PassengerId
Sex
female 314
male 577
In [6]:
# Graficamos con Pandas

pasajeros_sexo.plot.bar(
    y='PassengerId',
    title='Cantidad de pasajeros por Sexo',
    width= 0.3,
    #figsize=(10,5)
)

# Añadimos tema

plt.style.use(
    'ggplot'
)
In [7]:
pasajeros_sexo2 = pasajeros_sexo.reset_index() # pasamos sex a columna
pasajeros_sexo2
Out[7]:
Sex PassengerId
0 female 314
1 male 577
In [8]:
# graficamos con la libreria seaborn

sns.barplot(
    data=pasajeros_sexo2, 
    x='Sex', 
    y='PassengerId', 
).set(title='Cantidad de Pasajeros por Sexo')

plt.style.use(
    'ggplot'
)
In [9]:
# graficamos con la libreria matplotlib

plt.bar(
    pasajeros_sexo2['Sex'],
    pasajeros_sexo2['PassengerId']   
)

plt.style.use(
    'ggplot'
)

Gráfico de Pie¶

Un gráfico de pie es una representación visual simple y circular que muestra la proporción de diferentes categorías o partes de un todo. Se compone de secciones de diferentes tamaños, donde cada sección representa un porcentaje o fracción de la cantidad total. Este tipo de gráfico se utiliza para comunicar de manera rápida y clara la distribución relativa de las partes dentro de un conjunto de datos.

Características de un diagrama circular:

  • Estos gráficos sólo representan y comparan una variable.
  • A cada cualidad de la variable le pertenece una porción del gráfico.
  • Las cifras que se anotan sobre cada trozo se expresan en porcentajes, por eso son útiles cuando la información que tienes es en su mayoría numérica y son pocos datos.
  • Se usa para expresar proporcionalmente los distintos valores de la frecuencia de las variables.

En este caso a realizar la visualización del gráfico de pie con la librería pandas y plotly.

In [10]:
df.head(5)
Out[10]:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
In [11]:
pasajeros_sexo
Out[11]:
PassengerId
Sex
female 314
male 577
In [12]:
# Graficamos con pandas

pasajeros_sexo.plot.pie(
    y='PassengerId',
    startangle=90,
    autopct='%1.1f%%'
)

plt.style.use(
    'ggplot'
)
In [13]:
# Graficamos con plotly

fig = px.pie(
    pasajeros_sexo2, # lo hacemos con sex como columna mas no como indice
    names='Sex',
    values='PassengerId',
    title='Proporción de pasajeros por sexo',
    width=600, 
    height=400,
    template='plotly'
)
fig.show()
In [14]:
# EJEMPLO # 2

pasajeros_pclass = df.groupby('Pclass').agg({
    'PassengerId':'count'
})

pasajeros_pclass
Out[14]:
PassengerId
Pclass
1 216
2 184
3 491
In [15]:
# Graficamos con plotly
pasajeros_pclass2 = pasajeros_pclass.reset_index() # pasamos sex a columna
pasajeros_pclass2
Out[15]:
Pclass PassengerId
0 1 216
1 2 184
2 3 491
In [16]:
fig = px.pie(
    pasajeros_pclass2, # lo hacemos con sex como columna mas no como indice
    names='Pclass',
    values='PassengerId',
    title='Proporción de pasajeros por clase',
    hole=0.5,
    width=600, 
    height=400
)

fig.show()

Gráficos de Cajas¶

También conocido como diagrama de caja y bigotes, principalmente nos sirve para visualizar estadísticos de nuestras variables numéricas, es decir, es una representación visual que muestra de manera resumida la distribución de un conjunto de datos numéricos. Consiste en un rectángulo que se divide en cuatro partes principales: la mediana, el primer cuartil, el tercer cuartil y los bigotes. La mediana se representa como una línea en el centro del rectángulo, mientras que el primer y tercer cuartil se marcan como límites inferiores y superiores del rectángulo. Los bigotes se extienden desde los cuartiles hasta los valores mínimo y máximo observados, excluyendo los valores atípicos. Los gráficos de cajas son útiles para visualizar la dispersión, la simetría y la presencia de valores atípicos en un conjunto de datos.

  • Se utiliza cuando se quiere comparar diversos grupos por medio de sus estadísticos como lo son la mediana y cuartiles.

  • También es muy utilizado para visualizar si hay datos outliers dentro de nuestras variables o categorías.

  • No se debe utilizar para conocer la distribución de los datos.

Esta visualizacion la realizaremos con la librerias pandas, seaborn y plotly.

¿ Informacion de la edad de los hombres y mujeres del titanic.? (target)

In [17]:
df_age = df.dropna(subset = ['Age'], axis = 'index') # eliminamos valores nulos de la columna Age
df_age
Out[17]:
PassengerId Survived Pclass Name Sex Age SibSp Parch Ticket Fare Cabin Embarked
0 1 0 3 Braund, Mr. Owen Harris male 22.0 1 0 A/5 21171 7.2500 NaN S
1 2 1 1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38.0 1 0 PC 17599 71.2833 C85 C
2 3 1 3 Heikkinen, Miss. Laina female 26.0 0 0 STON/O2. 3101282 7.9250 NaN S
3 4 1 1 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35.0 1 0 113803 53.1000 C123 S
4 5 0 3 Allen, Mr. William Henry male 35.0 0 0 373450 8.0500 NaN S
... ... ... ... ... ... ... ... ... ... ... ... ...
885 886 0 3 Rice, Mrs. William (Margaret Norton) female 39.0 0 5 382652 29.1250 NaN Q
886 887 0 2 Montvila, Rev. Juozas male 27.0 0 0 211536 13.0000 NaN S
887 888 1 1 Graham, Miss. Margaret Edith female 19.0 0 0 112053 30.0000 B42 S
889 890 1 1 Behr, Mr. Karl Howell male 26.0 0 0 111369 30.0000 C148 C
890 891 0 3 Dooley, Mr. Patrick male 32.0 0 0 370376 7.7500 NaN Q

714 rows × 12 columns

In [18]:
# Graficamos con pandas

df_age.boxplot(
    column = 'Age',
    by = 'Sex'
)

plt.style.use(
    'classic'
)
In [43]:
# Graficamos con seaborn

sns.boxplot(
    data=df_age,
    x='Sex',
    y='Age'
)
sns.set_theme(
    'talk'
)
#sns.set_style('darkgrid')
In [20]:
# Graficamos con plotly

fig = px.box(
    df_age,
    x='Sex',
    y='Age',
    width=700, 
    height=500
)

fig.show()

Gráficos de Violines¶

Un gráfico de violines nos permite ver como están distribuidos los datos, manteniendo todas las bondades del diagrama de cajas, podríamos decir que es una representación visual el cual muestra la distribución y densidad de una variable cuantitativa en diferentes categorías o grupos. Combina un diagrama de caja y bigotes con curvas de densidad a cada lado.

In [21]:
# Graficamos con seaborn nota: este diagrama lo podemos no lo podemos graficar con pandas
In [22]:
sns.violinplot(
    data = df_age,
    x = 'Sex',
    y = 'Age'  
).set(title='Numero de Pasajeros por Sexo')
Out[22]:
[Text(0.5, 1.0, 'Numero de Pasajeros por Sexo')]
In [23]:
# Graficamos cpn plotly

fig = px.violin(
    df_age,
    x='Sex',
    y='Age',
    width=800, 
    height=500
)

fig.show()

Histograma¶

Muestra la distribución de una variable numérica como un conjunto de barras. Los datos numéricos se agrupan en "bins" (clases o grupos) según un rango de valores. Cada "bin" va a tener una barra. La altura de la barra representa cuantos puntos de datos existen dentro del rango del "bin". Usualmente, es el primer gráfico a realizar de todas las columnas numéricas de mi dataset, ya que me dice como se distribuyen mis datos.

Un histograma es una representación gráfica simple y visual de la distribución de datos en un conjunto. Consiste en una serie de barras adyacentes que muestran la frecuencia o la cantidad de veces que ocurre cada valor en el conjunto de datos. En el eje vertical se representa la frecuencia, mientras que en el eje horizontal se muestran los valores o rangos de valores del conjunto.

El histograma sirve para proporcionar una visión general de la distribución de los datos y para identificar patrones, tendencias y anomalías. Permite visualizar si los datos se agrupan en torno a ciertos valores, si siguen una distribución normal o si presentan valores atípicos. También puede ayudar a tomar decisiones informadas al analizar datos y comparar diferentes conjuntos de datos.

¿Distribución de edad de hombres y de mujeres?

In [24]:
# Graficamos con pandas

df.hist(
   'Age',
    by='Sex',
    bins=10
)
Out[24]:
array([<AxesSubplot:title={'center':'female'}>,
       <AxesSubplot:title={'center':'male'}>], dtype=object)
In [25]:
# Graficamos con seaborn

sns.histplot(
    data = df_age,
    x='Age'
)
Out[25]:
<AxesSubplot:xlabel='Age', ylabel='Count'>
In [26]:
# Graficamos con plotly

fig = px.histogram(
    df_age,
    x='Age',
    text_auto = True,
    width=800, 
    height=500
)

fig.show()

Gráfico de Densidad (kde Kernel Density Estimator)¶

Es una representación gráfica suave y continua de la distribución de una variable continua, que se construye utilizando funciones de kernel centradas en cada punto de datos para estimar la densidad en todo el rango de la variable,Los picos en la curva indican regiones con alta densidad de datos, mientras que los valles representan regiones con baja densidad este se utiliza debido a que en el histograma a veces es complicado visualizar la forma de mi distribución y como se sitribuyen los datos.

In [27]:
# Graficamos son seaborn
sns.histplot(
    data = df_age,
    x='Age',
    kde=True,
    stat='probability',
    hue='Sex'
)
Out[27]:
<AxesSubplot:xlabel='Age', ylabel='Probability'>

Gráfico de Linea¶

La utilidad de los gráficos de línea radica en su capacidad para mostrar tendencias y patrones a lo largo del tiempo o de una secuencia. Estos gráficos permiten identificar cambios y variaciones en los datos, así como la dirección y la magnitud de dichos cambios. Al conectar los puntos con líneas, se facilita la visualización de la trayectoria general de los datos, lo que ayuda a entender la evolución de una variable a lo largo del eje temporal o la secuencia establecida.

Además de mostrar tendencias, los gráficos de línea también permiten comparar varias series de datos en el mismo gráfico. Al representar múltiples líneas en un solo gráfico(Gráficos Multilineas), es posible visualizar la relación y la interacción entre diferentes variables, lo que ayuda a identificar correlaciones y patrones más complejos.

Tiene un objetivo similar al gráfico de barras. Nos sirve para mostrar diferencias de variables numéricas a través de mi variable en el Eje X. Sin embargo, es más útil cuando queremos mostrar tendencias de subida o de bajada de mi variable numérica. A diferencia del grafico de barras, el Eje X de izquierda a derecha suele representar una unidad de progresión ordenada de menor a mayor (ejemplo: días, años, meses, horas; es decir, usualmente unidades de tiempo). Es decir, Variables categóricas ordinales. A diferencia del gráfico de barras, yo puedo tener muchas categorías o puntos en el Eje X ya que no necesito dibujar barras en cada punto. El gráfico puede tener varias líneas que representan diferentes grupos. En este caso se denomina gráfico multilinea. Y obviamente, cada línea tiene que estar correctamente diferenciada.

Para este tipo de grafico lo ejemplificaremos con un dataset de ventas de varios supermercados de una misma cadena.

https://raw.githubusercontent.com/lkuffo/data-viz/main/data/tienda_ventas.csv

¿Analizar como ha cambiado la ventas de los productos por mes y año?

In [28]:
df_ventas = pd.read_csv('./datasets/tienda_ventas.csv', index_col='id') # en este caso utilizaremos el data set de evntas tienda
df_ventas
Out[28]:
date store_nbr family sales onpromotion
id
0 2013-01-01 1 AUTOMOTIVE 0.00000 0
1 2013-01-01 1 BABY CARE 0.00000 0
2 2013-01-01 1 BEAUTY 0.00000 0
3 2013-01-01 1 BEVERAGES 0.00000 0
4 2013-01-01 1 BOOKS 0.00000 0
... ... ... ... ... ...
2161561 2016-04-30 9 POULTRY 826.35300 0
2161562 2016-04-30 9 PREPARED FOODS 165.65399 0
2161563 2016-04-30 9 PRODUCE 2012.72700 1
2161564 2016-04-30 9 SCHOOL AND OFFICE SUPPLIES 10.00000 0
2161565 2016-04-30 9 SEAFOOD 32.18600 3

2161566 rows × 5 columns

calculamos todas la ventas de las diferentes tiendas en un mes

In [29]:
df_ventas['mes'] = df_ventas['date'].apply(lambda x: x[:7])
df_ventas
Out[29]:
date store_nbr family sales onpromotion mes
id
0 2013-01-01 1 AUTOMOTIVE 0.00000 0 2013-01
1 2013-01-01 1 BABY CARE 0.00000 0 2013-01
2 2013-01-01 1 BEAUTY 0.00000 0 2013-01
3 2013-01-01 1 BEVERAGES 0.00000 0 2013-01
4 2013-01-01 1 BOOKS 0.00000 0 2013-01
... ... ... ... ... ... ...
2161561 2016-04-30 9 POULTRY 826.35300 0 2016-04
2161562 2016-04-30 9 PREPARED FOODS 165.65399 0 2016-04
2161563 2016-04-30 9 PRODUCE 2012.72700 1 2016-04
2161564 2016-04-30 9 SCHOOL AND OFFICE SUPPLIES 10.00000 0 2016-04
2161565 2016-04-30 9 SEAFOOD 32.18600 3 2016-04

2161566 rows × 6 columns

In [30]:
ventas_mes = df_ventas.groupby('mes').agg({
    'sales':'sum'
})
ventas_mes.head(10)
Out[30]:
sales
mes
2013-01 1.032762e+07
2013-02 9.658960e+06
2013-03 1.142850e+07
2013-04 1.099346e+07
2013-05 1.159770e+07
2013-06 1.168934e+07
2013-07 1.125740e+07
2013-08 1.173779e+07
2013-09 1.179293e+07
2013-10 1.177562e+07
In [31]:
# Graficamos con pandas

ventas_mes.plot.line(
    y='sales',
    style='.-'
)
Out[31]:
<AxesSubplot:xlabel='mes'>
In [32]:
# Graficamos con plotly

fig = px.line(
    ventas_mes,
    x=ventas_mes.index.values,
    y='sales',
    width=700, 
    height=500
)
fig.show()

¿Comparar para el año 2015 las ventas de 3 familias de productos diferentes(Meats,Seafood y Dairy)?

In [33]:
df_ventas['year'] = df_ventas['date'].apply(lambda x: x[:4])
df_ventas
Out[33]:
date store_nbr family sales onpromotion mes year
id
0 2013-01-01 1 AUTOMOTIVE 0.00000 0 2013-01 2013
1 2013-01-01 1 BABY CARE 0.00000 0 2013-01 2013
2 2013-01-01 1 BEAUTY 0.00000 0 2013-01 2013
3 2013-01-01 1 BEVERAGES 0.00000 0 2013-01 2013
4 2013-01-01 1 BOOKS 0.00000 0 2013-01 2013
... ... ... ... ... ... ... ...
2161561 2016-04-30 9 POULTRY 826.35300 0 2016-04 2016
2161562 2016-04-30 9 PREPARED FOODS 165.65399 0 2016-04 2016
2161563 2016-04-30 9 PRODUCE 2012.72700 1 2016-04 2016
2161564 2016-04-30 9 SCHOOL AND OFFICE SUPPLIES 10.00000 0 2016-04 2016
2161565 2016-04-30 9 SEAFOOD 32.18600 3 2016-04 2016

2161566 rows × 7 columns

In [34]:
df_2015 = df_ventas[
    (df_ventas['year'] == '2015') & 
    (df_ventas['family'].isin(['SEAFOOD','MEATS','DAIRY']))
]
df_2015
Out[34]:
date store_nbr family sales onpromotion mes year
id
1297304 2015-01-01 1 DAIRY 0.000 0 2015-01 2015
1297320 2015-01-01 1 MEATS 0.000 0 2015-01 2015
1297328 2015-01-01 1 SEAFOOD 0.000 0 2015-01 2015
1297337 2015-01-01 10 DAIRY 0.000 0 2015-01 2015
1297353 2015-01-01 10 MEATS 0.000 0 2015-01 2015
... ... ... ... ... ... ... ...
1945902 2015-12-31 8 MEATS 382.466 0 2015-12 2015
1945910 2015-12-31 8 SEAFOOD 21.428 0 2015-12 2015
1945919 2015-12-31 9 DAIRY 878.000 1 2015-12 2015
1945935 2015-12-31 9 MEATS 377.211 21 2015-12 2015
1945943 2015-12-31 9 SEAFOOD 20.340 0 2015-12 2015

58968 rows × 7 columns

In [42]:
agrupacion = df_2015.groupby(['mes','family']).agg({
    'sales':'sum'
})
agrupacion.head(12)
Out[42]:
sales
mes family
2015-01 DAIRY 1.134521e+06
MEATS 5.431177e+05
SEAFOOD 4.046584e+04
2015-02 DAIRY 1.020747e+06
MEATS 4.987351e+05
SEAFOOD 3.606656e+04
2015-03 DAIRY 1.234851e+06
MEATS 5.465172e+05
SEAFOOD 4.380847e+04
2015-04 DAIRY 1.181180e+06
MEATS 5.223043e+05
SEAFOOD 3.998347e+04
In [36]:
pivot = agrupacion.reset_index(1).pivot(columns='family').droplevel(0,axis='columns')
pivot
Out[36]:
family DAIRY MEATS SEAFOOD
mes
2015-01 1134521.0 543117.728891 40465.835012
2015-02 1020747.0 498735.076839 36066.561003
2015-03 1234851.0 546517.159221 43808.473074
2015-04 1181180.0 522304.280744 39983.471003
2015-05 1293308.0 591691.899734 42506.832015
2015-06 1243588.0 565014.130035 38780.552004
2015-07 1244815.0 594903.677368 38535.588006
2015-08 1263428.0 581214.143026 37767.580998
2015-09 1224619.0 562711.633157 41906.374010
2015-10 1314827.0 580788.361242 41423.962963
2015-11 1283672.0 535908.927954 38823.761011
2015-12 1394582.0 567381.391078 33728.276973
In [37]:
# Graficamos con pandas

pivot.plot.line(
    subplots=True
)
Out[37]:
array([<AxesSubplot:xlabel='mes'>, <AxesSubplot:xlabel='mes'>,
       <AxesSubplot:xlabel='mes'>], dtype=object)
In [38]:
# Graficamos con plotly

fig = px.line(
    pivot,
    width=900, 
    height=500
)
fig.show()

Gráfico de Area¶

Es una representación visual que muestra cómo se distribuyen y cambian las diferentes categorías de datos a lo largo del tiempo o de una variable independiente, utilizando áreas apiladas para ilustrar la contribución relativa de cada categoría,tiene un objetivo similar al gráfico de barras. Nos sirve para mostrar diferencias de variables numéricas a través de mi variable en el Eje X. Sin embargo, es más útil cuando queremos mostrar tendencias de subida o de bajada de mi variable numérica. A diferencia del grafico de barras, el Eje X de izquierda a derecha suele representar una unidad de progresión ordenada de menor a mayor (ejemplo: días, años, meses, horas; es decir, usualmente unidades de tiempo). Es decir, Variables categóricas ordinales. A diferencia del gráfico de barras, yo puedo tener muchas categorías o puntos en el Eje X ya que no necesito dibujar barras en cada punto. El gráfico puede tener varias líneas que representan diferentes grupos.

Este tipo de gráfico es comúnmente utilizado en diversas áreas, como la visualización de datos financieros, la representación de cambios en la composición demográfica, la comparación de ventas por categoría de productos, entre otros. Ayuda a identificar rápidamente las tendencias y patrones en la distribución de los datos y a comparar la importancia relativa de las diferentes categorías en un contexto determinado.

In [39]:
# Graficamos con pandas

ventas_mes.plot.area(
    y='sales'
)
Out[39]:
<AxesSubplot:xlabel='mes'>
In [40]:
# grafico de areas apiladas
pivot.plot.area(
    stacked=True
)
Out[40]:
<AxesSubplot:xlabel='mes'>
In [41]:
# grafico de areas agrupadas
pivot.plot.area(
    stacked=False
)
Out[41]:
<AxesSubplot:xlabel='mes'>
In [ ]: